﻿//PlazaRouterConfigParser.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Plaza
{
	using System;
	using System.Linq;

	using Ecng.Common;

	using IniParser;

	/// <summary>
	/// Порционность создания файла логов.
	/// </summary>
	public enum LogFilePerDay
	{
		/// <summary>
		/// Новый файл создается при запуске приложения.
		/// </summary>
		AppStart = 0,

		/// <summary>
		/// Новый файл создается при смене даты. При этом к имени лог-файла добавляется дата в формате YYYYMMDD.
		/// </summary>
		NewDate = 1
	}

	/// <summary>
	/// Способ именования лог-файлов при использовании <see cref="PlazaRouterConfigParser.LogFilePerDay"/> равный <see cref="Plaza.LogFilePerDay.NewDate"/>.
	/// </summary>
	public enum LogFileNameType
	{
		/// <summary>
		/// Дата вставляется в конец имени файла.
		/// </summary>
		AppendDate = 0,

		/// <summary>
		/// Дата вставляется в середину имени файла, перед последней точкой.
		/// </summary>
		InsertDate = 1
	}

	/// <summary>
	/// Формат вывода времени в лог-файлах.
	/// </summary>
	public enum LogTime
	{
		/// <summary>
		/// Не выводить.
		/// </summary>
		Omit = 0,

		/// <summary>
		/// Выводить с точностью до секунды.
		/// </summary>
		Seconds = 1,

		/// <summary>
		/// Выводить с точностью до тысячных долей секунды.
		/// </summary>
		Milliseconds = 2
	}

	/// <summary>
	/// Парсер конфига роутера Plaza.
	/// </summary>
	public class PlazaRouterConfigParser
	{
		private readonly string _fileName;
		private readonly IniData _data;

		internal PlazaRouterConfigParser(string fileName)
		{
			_fileName = fileName;
			// Нужно указывать true (to try reading bad formed INI files),  
			// потому что для парсера [ProgMon] и [ProgMon:local_inter] - повтор одного ключа.
			_data = new FileIniDataParser().LoadFile(fileName, true);
		}

		/// <summary>
		/// Сохранить изменения.
		/// </summary>
		public void Save()
		{
			new FileIniDataParser().SaveFile(_fileName, _data);
		}

		private KeyDataCollection Router
		{
			get { return _data["P2MQRouter"]; }
		}

		private KeyDataCollection RouterInfo
		{
			get { return _data["ROUTEINFO"]; }
		}

		private KeyDataCollection Credentials
		{
			get { return _data["AS:NS"]; }
		}

		private KeyDataCollection Log
		{
			get { return _data["p2syslog"]; }
		}

		/// <summary>
		/// TCP-порт, который слушает роутер.
		/// </summary>
		public int Port
		{
			get
			{
				return Router["port"].To<int>();
			}
			set
			{
				Router["port"] = value.ToString();
			}
		}

		/// <summary>
		/// Ограничить доступ к роутеру локальным пользователям.
		/// По умолчнию его значение равно false.
		/// </summary>
		public bool RestrictLocalLogin
		{
			get
			{
				return Router["restrict_local_login"].To<int>().To<bool>();
			}
			set
			{
				Router["restrict_local_login"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Отключен ли алгоритм Nagl'e для входящих пакетов, что ускоряет их пересылку.
		/// По умолчнию его значение равно true.
		/// </summary>
		public bool TcpNoDelayIn
		{
			get
			{
				return Router["tcp_nodelayin"].To<int>().To<bool>();
			}
			set
			{
				Router["tcp_nodelayin"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Отключен ли алгоритм Nagl'e для исходящих пакетов, что ускоряет их пересылку.
		/// По умолчнию его значение равно true.
		/// </summary>
		public bool TcpNoDelayOut
		{
			get
			{
				return Router["tcp_nodelayout"].To<int>().To<bool>();
			}
			set
			{
				Router["tcp_nodelayout"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Имя пользователя.
		/// </summary>
		public string UserName
		{
			get
			{
				return Credentials["USERNAME"];
			}
			set
			{
				Credentials["USERNAME"] = value;
			}
		}

		/// <summary>
		/// Пароль.
		/// </summary>
		public string Password
		{
			get
			{
				return Credentials["PASSWORD"];
			}
			set
			{
				Credentials["USERNAME"] = value;
			}
		}

		/// <summary>
		/// Соединение по умочланию.
		/// Адрес указывается в формате {ip-адрес | имя FQDN}:{номер порта}.
		/// </summary>
		public string DefaultConnection
		{
			get
			{
				return RouterInfo["default"];
			}
			set
			{
				RouterInfo["default"] = value;
			}
		}

		/// <summary>
		/// Прямые соединения.
		/// </summary>
		public string[] DirectConnections
		{
			get
			{
				return RouterInfo
					.Where(d => d.KeyName == "direct")
					.Select(d => d.Value)
					.ToArray();
			}
		}

		/// <summary>
		/// Добавить прямое соединение.
		/// </summary>
		/// <param name="address">Адрес директного соединения в формате {ip-адрес | имя FQDN}:{номер порта}.</param>
		public void AddDirectConnection(string address)
		{
			if (address.IsEmpty())
				throw new ArgumentNullException("address");

			RouterInfo.AddKey("direct", address);
			//SetValue("[ROUTEINFO]", "direct", address);
		}

		/// <summary>
		/// Удалить прямое соединение.
		/// </summary>
		/// <param name="address">Адрес прямого соединения в формате {ip-адрес | имя FQDN}:{номер порта}.</param>
		public void RemoveDirectConnection(string address)
		{
			if (address.IsEmpty())
				throw new ArgumentNullException("address");

			//RouterInfo.RemoveKey("direct", address);
		}

		/// <summary>
		/// Удалить все прямые соединения.
		/// </summary>
		public void RemoveAllDirectConnections()
		{
			RouterInfo.RemoveKey("direct");
		}

		/// <summary>
		/// Путь и имя к файлу лога.
		/// </summary>
		public string LogFile
		{
			get
			{
				return Log["logfile"];
			}
			set
			{
				Log["logfile"] = value;
			}
		}

		/// <summary>
		/// Порционность создания файла логов.
		/// </summary>
		public LogFilePerDay LogFilePerDay
		{
			get
			{
				return Log["logfileperday"].To<int>().To<LogFilePerDay>();
			}
			set
			{
				Log["logfileperday"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Способ именования лог-файлов при использовании <see cref="LogFilePerDay"/> равный <see cref="Plaza.LogFilePerDay.NewDate"/>.
		/// </summary>
		public LogFileNameType LogFileNameType
		{
			get
			{
				return Log["logfilenametype"].To<int>().To<LogFileNameType>();
			}
			set
			{
				Log["logfilenametype"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Формат вывода времени в лог-файлах.
		/// </summary>
		public LogTime LogTime
		{
			get
			{
				return Log["logtime"].To<int>().To<LogTime>();
			}
			set
			{
				Log["logtime"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Включить-выключить использование файлового кэширования при записи в лог.
		/// </summary>
		public bool LogFileCache
		{
			get
			{
				return Log["logfilecache"].To<int>().To<bool>();
			}
			set
			{
				Log["logfilecache"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Копировать лог-сообщения в консоль.
		/// </summary>
		public bool LogToConsole
		{
			get
			{
				return Log["logtoconsole"].To<int>().To<bool>();
			}
			set
			{
				Log["logtoconsole"] = value.To<int>().ToString();
			}
		}

		/// <summary>
		/// Имя файла с настройками лог-сообщений.
		/// </summary>
		public string TraceIni
		{
			get
			{
				return Log["traceini"];
			}
			set
			{
				Log["traceini"] = value;
			}
		}
	}
}